package com.wdb007.venus.svc.biz.manager;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.ZhimaCreditScoreBriefGetRequest;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.api.response.ZhimaCreditScoreBriefGetResponse;
import com.wdb007.venus.svc.facade.constant.RspCodeEnum;
import com.wdb007.venus.svc.facade.exception.BizException;

@Component("alipayClientManager")
public class AlipayClientManager implements InitializingBean{

	private static final Logger logger = LoggerFactory.getLogger(AlipayClientManager.class);
	
	private String app_id ;
	
	private String gateway_url ;
	
	private String format = "json";
	
	private String charset = "utf-8" ;
	
	private String sign_type ;
	
	private String app_private_key;
	
	private String alipay_public_key ;
	
	private String notify_url = "";

	private AlipayClient alipayClient = null ;
	
	private String aliPaySubject ;
	
	private String aliPayTimeoutExpress ;
	
	private String aliQuickMsecurityPay ;
	@Autowired
	private ConfigInfoManager configInfoManager;
	/**
	 * 调用支付包的下单接口
	 * @param tradeNo
	 * @param amount
	 * @return
	 */
	public String generateOrder(String tradeNo, BigDecimal amount) {
		logger.info("下单请求参数: 交易号 [{}], 交易金额[{}]", tradeNo, amount);
		String orderStr = "";
		//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
		//SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		model.setSubject(aliPaySubject);
		model.setOutTradeNo(tradeNo);
		model.setTimeoutExpress(aliPayTimeoutExpress);
		model.setTotalAmount(amount.doubleValue()+"");
		model.setProductCode(aliQuickMsecurityPay);
		request.setBizModel(model);
		request.setNotifyUrl(notify_url);
		logger.info("调用ali下单接口时的请求参数: {}", JSON.toJSONString(request));
		try {
		        //这里和普通的接口调用不同，使用的是sdkExecute
		        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
		        logger.info("调用ali下单接口时的返回参数: {}", JSON.toJSONString(response));
		        orderStr = response.getBody();
		} catch (AlipayApiException e) {
		    	logger.error(e.getMessage(), e);
		    	//TODO 异常处理
		}
		return orderStr ;
	}
	/**
	 * 退款接口
	 * @return
	 */
	public String refund(String out_trade_no, String refund_amount, String refund_trade_no)  throws BizException{
		logger.info("退款参数 商户订单号： [{}], 退款金额:[{}]", out_trade_no, refund_amount);
		String data = null ;
		AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();//创建API对应的request类
		request.setBizContent("{" +
		"    \"out_trade_no\":\""+ out_trade_no+"\"," +
		"    \"refund_amount\":\"" + refund_amount + "\"," +
		"    \"out_request_no\":\"" + refund_trade_no + "\"" +
		"  }");//设置业务参数
		AlipayTradeRefundResponse response;
		try {
			response = alipayClient.execute(request);
			data = response.getBody();
			logger.info("退款返回值: {}" , data);
		} catch (AlipayApiException e) {
			logger.error("阿里支付退款异常", e);
			throw new BizException(RspCodeEnum.CALL_ALIPAY_REFUND_ERROR);
		}//通过alipayClient调用API，获得对应的response类
		return data ;
	}
	/**
	 * 调用阿里的验签方法
	 * @param params
	 * @return
	 */
	public boolean rsaCheckV1(Map<String,String> params) {
		logger.info("开始验签: {}", JSON.toJSONString(params));
		boolean flag = false ;
		try {
			 flag =AlipaySignature.rsaCheckV1(params, alipay_public_key, charset,"RSA2");
		} catch (AlipayApiException e) {
			logger.error(e.getMessage(), e);
		}
		logger.info("验签结果: {}", flag);
		return flag;
	}
	/**
	 * 支付宝订单查询接口
	 * @param out_trade_no 商品订单号
	 * @return
	 */
	public Map<String, String> queryOrderStatus(String out_trade_no) throws BizException{
		
		Map<String, String> result = new HashMap<String, String>();
		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();//创建API对应的request类
		request.setBizContent("{" +
				"   \"out_trade_no\":\""+out_trade_no+"\"" +
				"  }");//设置业务参数
		AlipayTradeQueryResponse response;
		try {
			//通过alipayClient调用API，获得对应的response类
			response = alipayClient.execute(request);
			//根据response中的结果继续业务逻辑处理
			logger.info("支付宝查询商户号[{}]返回结果: {}", out_trade_no, JSON.toJSONString(response.getBody()));
			JSONObject jsonObj = (JSONObject) JSON.parse(response.getBody());
			result.put("tradeStatus", response.getTradeStatus());
			result.put("tradeNo", (String)((Map)jsonObj.get("alipay_trade_query_response")).get("trade_no"));
			result.put("tradeInfo", ((JSONObject)jsonObj.get("alipay_trade_query_response")).toJSONString());
			return result;
		} catch (AlipayApiException e) {
			logger.error(e.getErrCode(), e);
			throw new BizException(RspCodeEnum.CALL_ALIPAY_ERROR);
		}
	}
	/**
	 * 查询对账单下载地址
	 * @param billDate
	 */
	public void downloadBill(String billDate, String filePath) {
		//创建API对应的request类
		AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
		request.setBizContent("{" +
		"    \"bill_type\":\"trade\"," +
		"    \"bill_date\":\"" + billDate +"\"" +
		"  }");//设置业务参数
		AlipayDataDataserviceBillDownloadurlQueryResponse response;
		try {
			response = alipayClient.execute(request);
			logger.info("billDownloadUrl: " + response.getBillDownloadUrl());
			logger.info(response.getBody());
			if(null != response.getBillDownloadUrl()) {
				download(response.getBillDownloadUrl(),filePath);
			}
		} catch (AlipayApiException e) {
			logger.error("阿里支付下载[" + billDate + "]对账单异常", e);
		}
	}
	
	public void download(String urlStr, String filePath) {
		//将接口返回的对账单下载地址传入urlStr
//		String urlStr = "http://dwbillcenter.alipay.com/downloadBillFile.resource?bizType=X&userId=X&fileType=X&bizDates=X&downloadFileName=X&fileId=X";
		//指定希望保存的文件路径
//		filePath = "/Users/fund_bill_20160405.csv";
		URL url = null;
		HttpURLConnection httpUrlConnection = null;
		InputStream fis = null;
		FileOutputStream fos = null;
		try {
		    url = new URL(urlStr);
		    httpUrlConnection = (HttpURLConnection) url.openConnection();
		    httpUrlConnection.setConnectTimeout(5 * 1000);
		    httpUrlConnection.setDoInput(true);
		    httpUrlConnection.setDoOutput(true);
		    httpUrlConnection.setUseCaches(false);
		    httpUrlConnection.setRequestMethod("GET");
		    httpUrlConnection.setRequestProperty("Charsert", "UTF-8");
		    httpUrlConnection.connect();
		    fis = httpUrlConnection.getInputStream();
		    byte[] temp = new byte[1024];
		    int b;
		    fos = new FileOutputStream(new File(filePath));
		    while ((b = fis.read(temp)) != -1) {
		        fos.write(temp, 0, b);
		        fos.flush();
		    }
		} catch (MalformedURLException e) {
		    e.printStackTrace();
		} catch (IOException e) {
		    e.printStackTrace();
		} finally {
		    try {
		        fis.close();
		        fos.close();
		        httpUrlConnection.disconnect();
		    } catch (NullPointerException e) {
		        e.printStackTrace();
		    } catch (IOException e) {
		        e.printStackTrace();
		    }
		}
	}
	
	public Map<String, Object> ZhimaCreditScoreBriefGet(String certNo, String transactionId, String realName, Integer admittanceScore) {
		ZhimaCreditScoreBriefGetRequest request = new ZhimaCreditScoreBriefGetRequest();
		request.setBizContent("{" +
				"\"transaction_id\":\""+transactionId+"\"," +
				"\"product_code\":\"w1010100000000002733\"," +
				"\"cert_type\":\"IDENTITY_CARD\"," +
				"\"cert_no\":\"" + certNo + "\"," +
				"\"name\":\"" + realName + "\"," +
				"\"admittance_score\":" + admittanceScore + "," +
				"\"linked_merchant_id\":\"2088721630869411\"" +
				"  }");
		ZhimaCreditScoreBriefGetResponse response;
		Map<String, Object> map = new HashMap<String, Object>(); 
		try {
			response = alipayClient.execute(request);
			if(response.isSuccess()){
				logger.info("查询芝麻信用成功: {}", JSON.toJSONString(response));
				map.put("admittanceFlag", response.getIsAdmittance());
				map.put("bizNo", response.getBizNo());
				map.put("querySuccess", 1);
			} else {
				logger.info("查询芝麻信用失败: {}", JSON.toJSONString(response));
				map.put("querySuccess", 0);
			}
		} catch (AlipayApiException e) {
			logger.error("查询用户芝麻信用分异常", e);
			map.put("querySuccess", -1);
		}
		
		return map;
	}
	public static void main(String[] args) {
		AlipayClientManager alipay = new AlipayClientManager();
//			alipay.queryOrderStatus("117_875d64182adf42ad190d8a1b81db7352");
//			alipay.ZhimaCreditScoreBriefGet(null);
	}
	
	public String getAppId() {
		return app_id;
	}
	@Override
	public void afterPropertiesSet() throws Exception {
		app_id = configInfoManager.getValue("APP_ID");
		gateway_url = configInfoManager.getValue("GATEWAY_URL");
		sign_type = configInfoManager.getValue("SIGN_TYPE");
		app_private_key  = configInfoManager.getValue("APP_PRIVATE_KEY");
		alipay_public_key = configInfoManager.getValue("ALIPAY_PUBLIC_KEY");
		notify_url = configInfoManager.getValue("NOTIFY_URL");
		aliPaySubject = configInfoManager.getValue("ALIPAY_SUBJECT");
		aliPayTimeoutExpress = configInfoManager.getValue("ALIPAY_TIMEOUTEXPRESS");
		aliQuickMsecurityPay = configInfoManager.getValue("ALI_QUICK_MSECURITY_PAY");
		//实例化客户端
		alipayClient = new DefaultAlipayClient(gateway_url, app_id, app_private_key, format, charset, alipay_public_key, sign_type);	}
}
